/*
 * @(#)RespondingGatewayQueryWebService.java
 * Date 2013-10-19
 * Version 1.0
 * Author Jim Horner
 * Copyright (c)2012
 */


package us.hornerscorners.lamppost.xca.ws;

import javax.annotation.Resource;

import javax.inject.Inject;

import javax.jws.HandlerChain;
import javax.jws.WebService;

import javax.xml.ws.BindingType;
import javax.xml.ws.WebServiceContext;

import javax.xml.ws.soap.Addressing;
import javax.xml.ws.soap.SOAPBinding;

import ihe.iti.xds_b._2007.RespondingGatewayQueryPortType;

import oasis.names.tc.ebxml_regrep.xsd.query._3.AdhocQueryRequest;
import oasis.names.tc.ebxml_regrep.xsd.query._3.AdhocQueryResponse;

import oasis.names.tc.ebxml_regrep.xsd.rim._3.RegistryObjectListType;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import us.hornerscorners.lamppost.atna.client.utils.AtnaUtils;

import us.hornerscorners.lamppost.config.IServiceConfig;

import us.hornerscorners.lamppost.exception.ServiceActionError;
import us.hornerscorners.lamppost.exception.SeverityType;

import us.hornerscorners.lamppost.ihecommon.config.IHEConfig;
import us.hornerscorners.lamppost.ihecommon.config.IHEServiceType;

import us.hornerscorners.lamppost.model.audit.AuditContext;
import us.hornerscorners.lamppost.model.audit.CodedValueType;

import us.hornerscorners.lamppost.registry.constant.ErrorCode;
import us.hornerscorners.lamppost.registry.constant.ResponseStatus;

import us.hornerscorners.lamppost.registry.inject.RegistryTarget;

import us.hornerscorners.lamppost.registry.transformer.xds
    .RegistryResponseTypeTransformer;

import us.hornerscorners.lamppost.ws.SOAPContextParser;

import us.hornerscorners.lamppost.xca.service.RespondingQueryService;


/**
 * Class description
 *
 *
 * @version        v1.0, 2013-10-19
 * @author         Jim Horner
 */
@WebService(
    portName = "RespondingGatewayQuery_Port_Soap12",
    serviceName = "RespondingGatewayQuery_Service",
    targetNamespace = "urn:ihe:iti:xds-b:2007",
    endpointInterface = "ihe.iti.xds_b._2007.RespondingGatewayQueryPortType",
    wsdlLocation = "WEB-INF/wsdl/xca/XCARespondingGatewayQuery.wsdl"
)
@HandlerChain(file = "META-INF/xca-handler-chain.xml")
@Addressing(enabled = true, required = true)
@BindingType(SOAPBinding.SOAP12HTTP_BINDING)
public class RespondingGatewayQueryWebService implements RespondingGatewayQueryPortType {

    /** Field description */
    @Inject
    private IHEConfig config;

    /** Field description */
    @Resource
    private WebServiceContext context;

    /** Field description */
    @Inject
    private SOAPContextParser contextParser;

    /** Field description */
    private final Logger logger = LoggerFactory.getLogger(getClass());

    /** Field description */
    @Inject
    private RespondingQueryService queryService;

    /** Field description */
    @Inject
    @RegistryTarget
    private RegistryResponseTypeTransformer responseTypeTransformer;

    /**
     * Method description
     *
     *
     * @param body
     *
     * @return
     */
    @Override
    public AdhocQueryResponse respondingGatewayCrossGatewayQuery(AdhocQueryRequest body) {

        AdhocQueryResponse result = null;

        try {

            logger.debug("XCA Responding - Stored Query started");

            CodedValueType eventType = AtnaUtils.createCodedValue("ITI-38",
                                           "IHE Transactions", "Cross Gateway Query");

            IServiceConfig serviceConfig =
                this.config.findServiceConfig(IHEServiceType.XCA);

            AuditContext auditContext = this.contextParser.parseAuditContext(context,
                                            eventType, serviceConfig);

            result = this.queryService.executeStoredQuery(auditContext, body);

        } catch (Exception e) {

            // create a response
            logger.error(e.getMessage(), e);

            ServiceActionError error =
                new ServiceActionError(ErrorCode.XDSRegistryError.getCode(),
                                       e.getMessage(), SeverityType.Error);

            result = new AdhocQueryResponse();
            result.setRegistryObjectList(new RegistryObjectListType());
            result.setStatus(ResponseStatus.Failure.getCode());
            result.setRegistryErrorList(
                this.responseTypeTransformer.createRegistryErrorList(getClass(), error));
        }

        return result;
    }
}
